home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / SLAX 6.0.8 / slax-6.0.8.iso / slax / base / 006-devel.lzm / usr / include / kgame / kgameio.h < prev    next >
Encoding:
C/C++ Source or Header  |  2005-10-10  |  17.8 KB  |  567 lines

  1. /*
  2.     This file is part of the KDE games library
  3.     Copyright (C) 2001 Martin Heni (martin@heni-online.de)
  4.     Copyright (C) 2001 Andreas Beckermann (b_mann@gmx.de)
  5.  
  6.     This library is free software; you can redistribute it and/or
  7.     modify it under the terms of the GNU Library General Public
  8.     License version 2 as published by the Free Software Foundation.
  9.  
  10.     This library is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.     Library General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU Library General Public License
  16.     along with this library; see the file COPYING.LIB.  If not, write to
  17.     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  18.     Boston, MA 02110-1301, USA.
  19. */
  20. /*
  21.     $Id: kgameio.h 465369 2005-09-29 14:33:08Z mueller $
  22. */
  23. #ifndef __KGAMEIO_H__
  24. #define __KGAMEIO_H__
  25.  
  26. #include <qstring.h>
  27. #include <qobject.h>
  28. #include <kdemacros.h>
  29. class KPlayer;
  30. class KGame;
  31. class KProcess;
  32.  
  33. /**
  34.  *  \short Base class for IO devices for games
  35.  *
  36.  *  This is the master class for
  37.  *  creating IO game devices. You cannot use it directly.
  38.  *  Either take one of the classes derived from it or
  39.  *  you have to create your own IO class derived from it (more probably).
  40.  *
  41.  *  The idea behind this class is to provide a common interface
  42.  *  for input devices into your game. By programming a KGameIO
  43.  *  device you need not distinguish the actual IO in the game
  44.  *  anymore. All work is done by the IO's. This allows very
  45.  *  easy reuse in other games as well.
  46.  *  A further advantage of using the IO's is that you can exchange
  47.  *  the control of a player at runtime. E.g. you switch a player
  48.  *  to be controlled by the computer or vice versa.
  49.  *
  50.  *  To achieve this you have to make all of your player inputs through a
  51.  *  KGameIO. You will usually call KGameIO::sendInput to do so. 
  52.  *
  53.  *  @author Martin Heni <martin@heni-online.de>
  54.  */
  55. class KDE_EXPORT KGameIO : public QObject
  56. {
  57.   Q_OBJECT
  58.  
  59. public:
  60.     /**
  61.      * Constructs a KGameIO object
  62.      */
  63.    KGameIO();
  64.    KGameIO(KPlayer*);
  65.    virtual ~KGameIO();
  66.  
  67.     /**
  68.      * Gives debug output of the game status
  69.      */
  70.    void Debug();
  71.  
  72.    /**
  73.     * Identifies the KGameIO via the rtti function
  74.     */
  75.    enum IOMode {GenericIO=1,KeyIO=2,MouseIO=4,ProcessIO=8,ComputerIO=16};
  76.    /**
  77.     * Run time idendification. Predefined values are from IOMode
  78.     * You MUST overwrite this in derived classes!
  79.     *
  80.     * @return rtti value
  81.     */
  82.    virtual int rtti() const = 0;  // Computer, network, local, ...
  83.    
  84.    /**
  85.     * This function returns the player who owns this IO
  86.     *
  87.     * @return the player this IO device is plugged into
  88.     */
  89.    KPlayer *player() const {return mPlayer;}
  90.  
  91.    /**
  92.     * Equivalent to player()->game()
  93.     * @return the @ref KGame object of this player
  94.     **/
  95.    KGame* game() const;
  96.  
  97.    /**
  98.     * Sets the player to which this IO belongs to. This
  99.     * is done automatically when adding a device to a 
  100.     * player
  101.     *
  102.     * @param p the player
  103.     */
  104.    void setPlayer(KPlayer *p) {mPlayer=p;}
  105.  
  106.    /**
  107.     * Init this device by setting the player and e.g. sending an
  108.     * init message to the device. This initialisation message is
  109.     * very useful for computer players as you can transmit the
  110.     * game status to them and only update this status in the setTurn
  111.     * commands.
  112.     *
  113.     * Called by @ref KPlayer::addGameIO only!
  114.     */
  115.    virtual void initIO(KPlayer *p);
  116.  
  117.     /**
  118.      * Notifies the IO device that the player's setTurn had been called
  119.      * Called by KPlayer
  120.      *
  121.      * This emits @ref signalPrepareTurn and sends the turn if the send
  122.      * parameter is set to true.
  123.      *
  124.      * @param b turn is true/false
  125.      */
  126.     virtual void notifyTurn(bool b);
  127.  
  128.     /**
  129.      * Send an input message using @ref KPlayer::forwardInput
  130.      **/
  131.     bool sendInput(QDataStream& stream, bool transmit = true, Q_UINT32 sender = 0);
  132.  
  133. signals:
  134.     /**
  135.      * Signal generated when @ref KPlayer::myTurn changes. This can either be
  136.      * when you get the turn status or when you lose it.
  137.      *
  138.      * The datastream has to be filled with a move. If you set (or leave) the
  139.      * send parameter to FALSE then nothing happens: the datastream will be
  140.      * ignored. If you set it to TRUE @ref sendInput is used to
  141.      * send the move.
  142.      *
  143.      * Often you want to ignore this signal (leave send=FALSE) and send the
  144.      * message later. This is usually the case for a human player as he probably
  145.      * doesn't react immediately. But you can still use this e.g. to notify the
  146.      * player about the turn change. 
  147.      *
  148.      * Example:
  149.      * \code
  150.      *  void GameWindow::slotPrepareTurn(QDataStream &stream,bool b,KGameIO *input,bool * )
  151.      *  {
  152.      *    KPlayer *player=input->player();
  153.      *    if (!player->myTurn()) return ;
  154.      *    if (!b) return ;        // only do something on setTurn(true)
  155.      *    stream << 1 << 2 << 3;  // Some data for the process
  156.      *  }
  157.      * \endcode
  158.      *
  159.      * @param io the KGameIO object itself
  160.      * @param stream the stream into which the move will be written
  161.      * @param turn the argument of setTurn
  162.      * @param send set this to true to send the generated move using @ref
  163.      * sendInput
  164.      **/
  165.     void signalPrepareTurn(QDataStream & stream, bool turn, KGameIO *io, bool * send);
  166.  
  167.  
  168. private:
  169.    KPlayer *mPlayer;
  170. };
  171.  
  172. /**
  173.  *  The KGameKeyIO class. It is used to process keyboard input
  174.  *  from a widget and create moves for the player it belongs to.
  175.  *  @author Martin Heni <martin@heni-online.de>
  176.  */
  177. class KDE_EXPORT KGameKeyIO : public KGameIO
  178. {
  179.   Q_OBJECT
  180.  
  181. public:
  182.     /**
  183.      * Create a keyboard input devices. All keyboards
  184.      * inputs of the given widgets are passed through a signal
  185.      * handler signalKeyEvent and can be used to generate
  186.      * a valid move for the player.
  187.      * Note the widget you pass to the constructor must be
  188.      * the main window of your application, e.g. view->parentWidget()
  189.      * as QT does not forward your keyevents otherwise. This means
  190.      * that this might be a different widget comapred to the one you
  191.      * use for mouse inputs!
  192.      * Example:
  193.      * \code
  194.      * KGameKeyIO *input;
  195.      *  input=new KGameKeyIO(myWidget);
  196.      *  connect(input,SIGNAL(signalKeyEvent(KGameIO *,QDataStream &,QKeyEvent *,bool *)),
  197.      *          this,SLOT(slotKeyInput(KGameIO *,QDataStream &,QKeyEvent *,bool *)));
  198.      * \endcode
  199.      *
  200.      * @param parent The parents widget whose keyboard events * should be grabbed
  201.      */
  202.     KGameKeyIO(QWidget *parent);
  203.     virtual ~KGameKeyIO();
  204.  
  205.     /**
  206.      * The idendification of the IO
  207.      *
  208.      * @return KeyIO
  209.      */
  210.     virtual int rtti() const;
  211.  
  212. signals:
  213.       /**
  214.        * Signal handler for keyboard events. This function is called
  215.        * on every keyboard event. If appropriate it can generate a
  216.        * move for the player the device belongs to. If this is done
  217.        * and the event is eaten eatevent needs to be set to true.
  218.        * What move you generate (i.e. what you write to the stream)
  219.        * is totally up to you as it will not be evaluated but forwared
  220.        * to the player's/game's  input move function
  221.        * Example:
  222.        * \code
  223.        * KPlayer *player=input->player(); // Get the player
  224.        * Q_INT32 key=e->key();
  225.        * stream << key;
  226.        * eatevent=true;
  227.        * \endcode
  228.        *
  229.        * @param io the IO device we belong to
  230.        * @param stream the stream where we write our move into
  231.        * @param m The QKeyEvent we can evaluate
  232.        * @param eatevent set this to true if we processed the event
  233.        */
  234.       void signalKeyEvent(KGameIO *io,QDataStream &stream,QKeyEvent *m,bool *eatevent);
  235.  
  236. protected:
  237.        /**
  238.        * Internal method to process the events
  239.        */
  240.        bool eventFilter( QObject *o, QEvent *e );
  241. };
  242.  
  243. /**
  244.  *  The KGameMouseIO class. It is used to process mouse input
  245.  *  from a widget and create moves for the player it belongs to.
  246.  *  @author Martin Heni <martin@heni-online.de>
  247.  */
  248. class KDE_EXPORT KGameMouseIO : public KGameIO
  249. {
  250.   Q_OBJECT
  251.     
  252. public:
  253.     /**
  254.      * Creates a mouse IO device. It captures all mouse
  255.      * event of the given widget and forwards them to the
  256.      * signal handler signalMouseEvent.
  257.      * Example:
  258.      * \code
  259.      * KGameMouseIO *input;
  260.      * input=new KGameMouseIO(mView);
  261.      * connect(input,SIGNAL(signalMouseEvent(KGameIO *,QDataStream &,QMouseEvent *,bool *)),
  262.      *        this,SLOT(slotMouseInput(KGameIO *,QDataStream &,QMouseEvent *,bool *)));
  263.      * \endcode
  264.      *
  265.      * @param parent The widget whose events should be captured
  266.      * @param trackmouse enables mouse tracking (gives mouse move events)
  267.      */
  268.     KGameMouseIO(QWidget *parent,bool trackmouse=false);
  269.     virtual ~KGameMouseIO();
  270.     
  271.     /**
  272.      * Manually activate or deactivate mouse tracking
  273.      *
  274.      * @param b true = tracking on
  275.      */
  276.     void setMouseTracking(bool b);
  277.     /**
  278.      * The idendification of the IO
  279.      *
  280.      * @return MouseIO
  281.      */
  282.     virtual int rtti() const; 
  283.  
  284. signals:
  285.       /**
  286.        * Signal handler for mouse events. This function is called
  287.        * on every mouse event. If appropriate it can generate a
  288.        * move for the player the device belongs to. If this is done
  289.        * and the event is eaten eatevent needs to be set to true.
  290.        * @see signalKeyEvent
  291.        * Example:
  292.        * \code
  293.        * KPlayer *player=input->player(); // Get the player
  294.        * Q_INT32 button=e->button();
  295.        * stream << button;
  296.        * eatevent=true;
  297.        * \endcode
  298.        *
  299.        * @param io the IO device we belong to
  300.        * @param stream the stream where we write our move into
  301.        * @param m The QMouseEvent we can evaluate
  302.        * @param eatevent set this to true if we processed the event
  303.        */
  304.       void signalMouseEvent(KGameIO *io,QDataStream &stream,QMouseEvent *m,bool *eatevent);
  305.  
  306. protected:
  307.       /**
  308.       * Internal event filter
  309.       */
  310.       bool eventFilter( QObject *o, QEvent *e );
  311.  
  312. };
  313.  
  314.  
  315. /**
  316.  *  The KGameProcessIO class. It is used to create a computer player
  317.  *  via a separate process and communicate transparetly with it.
  318.  *  Its counterpart is the @ref KGameProcess class which needs
  319.  *  to be used by the computer player. See its documentation
  320.  *  for the definition of the computer player.
  321.  *  @author Martin Heni <martin@heni-online.de>
  322.  */
  323. class KDE_EXPORT KGameProcessIO : public KGameIO
  324. {
  325.   Q_OBJECT
  326.     
  327. public:
  328.     /** 
  329.      * Creates a computer player via a separate process. The process
  330.      * name is given as fully qualified filename. 
  331.      * Example:
  332.      * \code
  333.      * KGameProcessIO *input;
  334.      *   input=new KGameProcessIO(executable_file);
  335.      *  connect(input,SIGNAL(signalPrepareTurn(QDataStream &,bool,KGameIO *,bool *)),
  336.      *          this,SLOT(slotPrepareTurn(QDataStream &,bool,KGameIO *,bool *)));
  337.      *  connect(input,SIGNAL(signalProcessQuery(QDataStream &,KGameProcessIO *)),
  338.      *          this,SLOT(slotProcessQuery(QDataStream &,KGameProcessIO *)));
  339.      * \endcode
  340.      *
  341.      * @param name the filename of the process to start
  342.      */
  343.     KGameProcessIO(const QString& name);
  344.  
  345.     /**
  346.      * Deletes the process input devices 
  347.      */
  348.     virtual ~KGameProcessIO();
  349.  
  350.     /**
  351.      * The idendification of the IO
  352.      *
  353.      * @return ProcessIO
  354.      */
  355.     int rtti() const;
  356.     
  357.     /**
  358.      * Send a message to the process. This is analogous to the sendMessage
  359.      * commands of KGame. It will result in a signal of the computer player
  360.      * on which you can react in the process player.
  361.      *
  362.      * @param stream  - the actual data
  363.      * @param msgid - the id of the message
  364.      * @param receiver - not used
  365.      * @param sender - who send the message
  366.      */
  367.     void sendMessage(QDataStream &stream,int msgid, Q_UINT32 receiver, Q_UINT32 sender);
  368.  
  369.     /**
  370.      * Send a system message to the process. This is analogous to the sendMessage
  371.      * commands of KGame. It will result in a signal of the computer player
  372.      * on which you can react in the process player.
  373.      *
  374.      * @param stream  - the actual data
  375.      * @param msgid - the id of the message
  376.      * @param receiver - not used
  377.      * @param sender - who send the message
  378.      */
  379.     void sendSystemMessage(QDataStream &stream, int msgid, Q_UINT32 receiver, Q_UINT32 sender);
  380.  
  381.     /** 
  382.      * Init this device by setting the player and e.g. sending an
  383.      * init message to the device. Calling this function will emit
  384.      * the IOAdded signal on which you can react and initilise the
  385.      * computer player. 
  386.      * This function is called automatically when adding the IO to
  387.      * a player.
  388.      */
  389.     void initIO(KPlayer *p);
  390.  
  391.     /**
  392.      *  Notifies the IO device that the player's setTurn had been called
  393.      *  Called by KPlayer. You can react on the @ref signalPrepareTurn to
  394.      *  prepare a message for the process, i.e. either update it on
  395.      * the changes made to the game since the last turn or the initIO
  396.      * has been called or transmit your gamestatus now.
  397.      *
  398.      *  @param turn is true/false
  399.      */
  400.     virtual void notifyTurn(bool turn);
  401.  
  402.   protected:
  403.     /**
  404.      * Internal ~ombined function for all message handling 
  405.      **/
  406.     void sendAllMessages(QDataStream &stream,int msgid, Q_UINT32 receiver, Q_UINT32 sender, bool usermsg);
  407.  
  408.   protected slots:
  409.   /**
  410.   * Internal message handler to receive data from the process
  411.   */
  412.     void receivedMessage(const QByteArray& receiveBuffer);
  413.  
  414.   
  415. signals:
  416.   /**
  417.    * A computer query message is received. This is a 'dummy'
  418.    * message sent by the process if it needs to communicate
  419.    * with us. It is not forwarded over the network.
  420.    * Reacting to this message allows you to 'answer' questions
  421.    * of the process, e.g. sending addition data which the process
  422.    * needs to calculate a move.
  423.    *
  424.    * Example:
  425.    * \code
  426.    *  void GameWindow::slotProcessQuery(QDataStream &stream,KGameProcessIO *reply)
  427.    *  {
  428.    *    int no;
  429.    *    stream >> no;  // We assume the process sends us an integer question numner
  430.    *    if (no==1)     // but YOU have to do this in the process player
  431.    *    {
  432.    *      QByteArray buffer;
  433.    *      QDataStream out(buffer,IO_WriteOnly);
  434.    *      reply->sendSystemMessage(out,4242,0,0);  // lets reply something...
  435.    *    }
  436.    *  }
  437.    * \endcode
  438.    */
  439.   void signalProcessQuery(QDataStream &stream,KGameProcessIO *me);
  440.  
  441.   /**
  442.   * Signal generated when the computer player is added. 
  443.   * You can use this to communicated with the process and
  444.   * e.g. send initialisation information to the process.
  445.   *
  446.   * @param game the KGameIO object itself
  447.   * @param stream the stream into which the move will be written
  448.   * @param p the player itself
  449.   * @param send set this to false if no move should be generated
  450.   */
  451.   void signalIOAdded(KGameIO *game,QDataStream &stream,KPlayer *p,bool *send);
  452.  
  453.  
  454. protected:
  455.  
  456. private:
  457.   class KGameProcessIOPrivate;
  458.   KGameProcessIOPrivate* d;
  459. };
  460.  
  461. /**
  462.  *  \brief KGameIO variant for real-time games
  463.  *
  464.  *  The KGameComputerIO class. It is used to create a LOCAL computer player
  465.  *  and communicate transparently with it. 
  466.  *  Question: Is this needed or is it overwritten anyway for a real game?
  467.  *
  468.  *  You most probably don't want to use this if you want to design a turn based
  469.  *  game/player. You'll rather use @ref KGameIO directly, i.e. subclass it
  470.  *  yourself. You just need to use @ref KGameIO::signalPrepareTurn and/or @ref
  471.  *  KGameIO::notifyTurn there.
  472.  *
  473.  *  This is rather meant to be of use in real time games.
  474.  *
  475.  *  @author  <b_mann@gmx.de>
  476.  */
  477. class KDE_EXPORT KGameComputerIO : public KGameIO
  478. {
  479.   Q_OBJECT
  480.     
  481. public:
  482.     /** 
  483.      * Creates a LOCAL computer player 
  484.      *
  485.      */
  486.     KGameComputerIO();
  487.     KGameComputerIO(KPlayer* player);
  488.     ~KGameComputerIO();
  489.  
  490.     int rtti() const;
  491.  
  492.     /**
  493.      * The number of advance calls until the player (or rather: the IO)
  494.      * does something (default: 1). 
  495.      **/
  496.     void setReactionPeriod(int advanceCalls);
  497.     int reactionPeriod() const;
  498.  
  499.     /**
  500.      * Start a QTimer which calls advance every @p ms milli seconds.
  501.      **/
  502.     void setAdvancePeriod(int ms);
  503.  
  504.     void stopAdvancePeriod();
  505.  
  506.     /**
  507.      * Ignore calls number of advance calls. if calls is -1 then all 
  508.      * following advance calls are ignored until unpause is called.
  509.      *
  510.      * This simply prevents the internal advance counter to be increased.
  511.      *
  512.      * You may want to use this to emulate a "thinking" computer player. Note
  513.      * that this means if you increase the advance period (see 
  514.      * setAdvancePeriod), i.e. if you change the speed of your game, your
  515.      * computer player thinks "faster".
  516.      * @param calls Number of advance calls to be ignored
  517.      **/
  518.     void pause(int calls = -1);
  519.  
  520.     /**
  521.      * Equivalent to pause(0). Immediately continue to increase the internal
  522.      * advance counter.
  523.      **/
  524.     void unpause();
  525.     
  526. public slots:
  527.     /**
  528.      * Works kind of similar to QCanvas::advance. Increase the internal
  529.      * advance counter. If @p reactionPeriod is reached the counter is set back to
  530.      * 0 and @ref signalReaction is emitted. This is when the player is meant 
  531.      * to do something (move its units or so).
  532.      *
  533.      * This is very useful if you use QCanvas as you can use this in your
  534.      * QCanvas::advance call. The advantage is that if you change the speed
  535.      * of the game (i.e. change QCanvas::setAdvancePeriod) the computer
  536.      * player gets slower as well.
  537.      *
  538.      * If you don't use QCanvas you can use setAdvancePeriod to get
  539.      * the same result. Alternatively you can just use a QTimer.
  540.      * 
  541.      **/
  542.     virtual void advance();
  543.   
  544. signals:
  545.     /**
  546.      * This signal is emitted when your computer player is meant to do
  547.      * something, or better is meant to be allowed to do something.
  548.      **/
  549.     void signalReaction();
  550.  
  551. protected:
  552.     /**
  553.      * Default implementation simply emits signalReaction
  554.      **/
  555.     virtual void reaction();
  556.  
  557. private:
  558.     void init();
  559.  
  560. private:
  561.     class KGameComputerIOPrivate;
  562.     KGameComputerIOPrivate* d;
  563. };
  564.  
  565.  
  566. #endif
  567.